package com.mall.shopping.services.cart;

import com.mall.shopping.ICartService;
import com.mall.shopping.constants.ShoppingRetCode;
import com.mall.shopping.converter.CartItemConverter;
import com.mall.shopping.dal.entitys.Item;
import com.mall.shopping.dal.persistence.ItemMapper;
import com.mall.shopping.dto.*;
import com.mall.shopping.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.redisson.api.RBucket;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * https://www.jb51.net/article/216604.htm RMap的API用法一览
 * 购物车用redis非关系型数据库来存储数据
 * key是userId，  value（一个hashmap数据结构）
 * Field          value
 * productId      商品的对象
 */
@Slf4j
@Component
@Service
public class CartServiceImpl implements ICartService {
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    ItemMapper itemMapper;

    @Override
    public CartListByIdResponse getCartListById(CartListByIdRequest request) {
        CartListByIdResponse response = new CartListByIdResponse();
        try {
            request.requestCheck();
            Long userId = request.getUserId();
            RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
            Collection<CartProductDto> cartProductDtos = map.readAllValues();
            //将collection是集合转成List
            ArrayList<CartProductDto> productDtos = new ArrayList<>(cartProductDtos);
            response.setCartProductDtos(productDtos);
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("CartServiceImpl listCart 展示购物车中所有商品 occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public AddCartResponse addToCart(AddCartRequest request) {
        AddCartResponse response = new AddCartResponse();
        //商品的id，也就是前端的productId，数据库里的itemId
        Long itemId = request.getItemId();
        Long userId = request.getUserId();
        try {
            request.requestCheck();
            Item item = itemMapper.selectByPrimaryKey(itemId);
            CartProductDto cartProductDto = CartItemConverter.item2Dto(item);
            cartProductDto.setProductNum((long) request.getNum());
            //TODO:检查这里的checked字段是什么意思 是选中的意思，那总不能放一个就是checked是true吧
            cartProductDto.setChecked("true");
            //redis在getMap的一瞬间就直接创建了一个新的map
            RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
            CartProductDto product = map.get(itemId);
            if (product == null) {
                map.put(itemId, cartProductDto);
            } else {
                cartProductDto.setProductNum(product.getProductNum() + cartProductDto.getProductNum());
                map.put(itemId, cartProductDto);
            }
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            log.error("CartServiceImpl.addToCart 添加购物车 occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public UpdateCartNumResponse updateCartNum(UpdateCartNumRequest request) {
        UpdateCartNumResponse response = new UpdateCartNumResponse();
        Long userId = request.getUserId();
        Long itemId = request.getItemId();
        Integer num = request.getNum();
        String checked = request.getChecked();
        try {
            request.requestCheck();
            RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
            CartProductDto cartProductDto = map.get(itemId);
            cartProductDto.setProductNum(Long.valueOf(num));
            cartProductDto.setChecked(checked);
            boolean replace = map.replace(itemId, map.get(itemId), cartProductDto);
            if (replace) {
                response.setCode(ShoppingRetCode.SUCCESS.getCode());
                response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            } else {
                response.setCode(ShoppingRetCode.SYSTEM_ERROR.getCode());
                response.setMsg(ShoppingRetCode.SYSTEM_ERROR.getMessage());
            }
        } catch (Exception e) {
            log.error("CartServiceImpl.updateCartNum 更新购物车 occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public CheckAllItemResponse checkAllCartItem(CheckAllItemRequest request) {
        CheckAllItemResponse response = new CheckAllItemResponse();
        Long userId = request.getUserId();
        String checked = request.getChecked();
        try {
            request.requestCheck();
            RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
            Collection<CartProductDto> cartProductDtos = map.readAllValues();
            List<CartProductDto> replaceDTOs = new ArrayList<>();
            for (CartProductDto dto : cartProductDtos) {
                dto.setChecked(checked);
                CartProductDto oldDTO = map.replace(dto.getProductId(), dto);
                replaceDTOs.add(oldDTO);
            }
            if (!CollectionUtils.isEmpty(replaceDTOs)) {
                response.setCode(ShoppingRetCode.SUCCESS.getCode());
                response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            }else {
                response.setCode(ShoppingRetCode.SYSTEM_ERROR.getCode());
                response.setMsg(ShoppingRetCode.SYSTEM_ERROR.getMessage());
            }
        } catch (Exception e) {
            log.error("CartServiceImpl.checkAllCartItem 全选购物车中的商品 occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }

    @Override
    public DeleteCartItemResponse deleteCartItem(DeleteCartItemRequest request) {
        DeleteCartItemResponse response = new DeleteCartItemResponse();
        Long itemId = request.getItemId();
        Long userId = request.getUserId();

        try {
            request.requestCheck();
            RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
            CartProductDto deleteProduct = map.remove(itemId);
            if (deleteProduct != null) {
                response.setCode(ShoppingRetCode.SUCCESS.getCode());
                response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            }else {
                response.setCode(ShoppingRetCode.SYSTEM_ERROR.getCode());
                response.setMsg(ShoppingRetCode.SYSTEM_ERROR.getMessage());
            }
        } catch (Exception e) {
            log.error("CartServiceImpl.deleteCartItem 删除购物车 occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public DeleteCheckedItemResposne deleteCheckedItem(DeleteCheckedItemRequest request) {
        DeleteCheckedItemResposne response = new DeleteCheckedItemResposne();
        Long userId = request.getUserId();
        try {
            request.requestCheck();
            RMap<Long, CartProductDto> map = redissonClient.getMap(userId.toString());
            Collection<CartProductDto> dtos = map.readAllValues();
            List<CartProductDto> productList = new ArrayList<>(dtos);
            List<CartProductDto> deleteList = new ArrayList<>();
            for (CartProductDto product : productList) {
                if (product.getChecked().equals("true")) {
                    CartProductDto remove = map.remove(product.getProductId());
                    deleteList.add(remove);
                }
            }

            if (!CollectionUtils.isEmpty(deleteList)) {
                response.setCode(ShoppingRetCode.SUCCESS.getCode());
                response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            }else {
                response.setCode(ShoppingRetCode.SYSTEM_ERROR.getCode());
                response.setMsg(ShoppingRetCode.SYSTEM_ERROR.getMessage());
            }
        } catch (Exception e) {
            log.error("CartServiceImpl.deleteCheckedItem 删除购物车选中物品 occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    /**
     * 没有清空购物车这个接口
     *
     * @param request
     * @return
     */
    @Override
    public ClearCartItemResponse clearCartItemByUserID(ClearCartItemRequest request) {
        return null;
    }
}